package com.thinkingcoder.tcregistry.health;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import com.thinkingcoder.tcregistry.model.meta.InstanceMeta;
import com.thinkingcoder.tcregistry.service.RegistryService;
import com.thinkingcoder.tcregistry.service.TcRegistryService;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class TcHealthChecker implements HealthChecker {

    RegistryService registryService;

    final int interval = 10_000;
    final int timeout = 20_000;

    final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);

    public TcHealthChecker(RegistryService registryService) {
        this.registryService = registryService;
    }

    @Override
    public void start() {
        executor.scheduleWithFixedDelay(() -> {
            log.info(" ===> Health checker running...");

            Long now = System.currentTimeMillis();

            TcRegistryService.TIMESTAMPS.keySet().stream().forEach(serviceNameAndInstanceUrl -> {
                Long timestamp = TcRegistryService.TIMESTAMPS.get(serviceNameAndInstanceUrl);
                if (now - timestamp > timeout) {
                    log.info(" ===> Health checker: {} is down", serviceNameAndInstanceUrl);
                    int index = serviceNameAndInstanceUrl.indexOf("@");
                    String serviceName = serviceNameAndInstanceUrl.substring(0, index);
                    String instanceUrl = serviceNameAndInstanceUrl.substring(index + 1);
                    InstanceMeta instance = InstanceMeta.from(instanceUrl);
                    registryService.unregister(serviceName, instance);
                    TcRegistryService.TIMESTAMPS.remove(serviceNameAndInstanceUrl);
                }
            });

        }, interval, interval, TimeUnit.MILLISECONDS);
    }

    @Override
    public void stop() {
        executor.shutdown();
    }
}
